package com.study.zouchao.superproject.modifyuserinfo.presenter;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;

import com.google.common.escape.UnicodeEscaper;
import com.study.zouchao.superproject.login.model.entity.User;
import com.study.zouchao.superproject.logininterceptor.LoginStatusUtil;
import com.study.zouchao.superproject.modifyuserinfo.contract.IModifyUserInfoContract;
import com.study.zouchao.superproject.modifyuserinfo.model.entity.updateimg.UpdateImgResult;
import com.study.zouchao.superproject.modifyuserinfo.model.entity.updateinfo.ModifyUseInfoBean;
import com.study.zouchao.superproject.modifyuserinfo.model.entity.updateinfo.ModifyUserInfoResult;
import com.study.zouchao.superproject.modifyuserinfo.model.impl.ModifyUserInfoModel;
import com.study.zouchao.superproject.modifyuserinfo.model.impl.UpdateHeadImgModel;
import com.study.zouchao.superproject.util.App;
import com.study.zouchao.superproject.util.BitmapUtil;
import com.study.zouchao.superproject.util.FileUtil;
import com.study.zouchao.superproject.util.LogLongUtil;
import com.study.zouchao.superproject.util.RandomUtils;
import com.study.zouchao.superproject.util.RegexUtils;
import com.study.zouchao.superproject.util.StringUtils;
import com.study.zouchao.superproject.util.SystemUtils;
import com.study.zouchao.superproject.util.ToastUtils;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import rx.Subscription;
import rx.functions.Action1;

/**
 * Created by Administrator on 2017/1/29.
 */

public class ModifyUserInfoPresenter implements IModifyUserInfoContract.IModifyUserInfoPresenter {
    private static final String TAG = "ModifyUserInfoP";
    private Context mContext;
    //v
    private IModifyUserInfoContract.IModifyUserInfoView mView;
    //m
    private IModifyUserInfoContract.IModifyUserInfoModel mModel;
    //提交更改的Sup      , 上传头像的Sup
    private Subscription mSup, mSupUpdateImg;

    private static final int CHOOSE_PICTURE_FROM_DISK = 0;

    private static final int TAKE_PICTURE = 1;

    private static final int CROP_SMALL_PICTURE = 2;

    //每次拍照后这个图片都会被替换
    private static Uri mTempUri;

    //打开摄像头拍照后生成的(临时)图片
    private static String TEMP_IMG_NAME = "";
    //上传头像的filename参数（实际上和 TEMP_IMG_NAME一致）
    private String mFilename = "";
    //图片扩展名
    private static final String IMG_EXPAND_NAME = ".png";

    //父文件夹名
    private static final String DIR_NAME = "_Study";
    //子文件夹名
    private static final String SUB_DIR_NAME = "head_img";
    //头像图片
    private static String HEAD_IMG_NAME = "testPic.png";
    //正则匹配：nickname
    private static final String REG_NICKNAME = "^[\\u4E00-\\u9FA5A-Za-z0-9_]+$";
    //正则匹配：resume
    private static final String REG_RESUME = "^[\\u4E00-\\u9FA5A-Za-z0-9_]+$";

    public ModifyUserInfoPresenter(Context context, IModifyUserInfoContract.IModifyUserInfoView view) {
        mView = view;
        mContext = context;
        mModel = new ModifyUserInfoModel();
        initUserInfo();
    }

    /**
     * 显示更改前的用户信息数据
     */
    @Override
    public void initUserInfo() {
        //得到登录成功后 保存在本地的 用户信息
        User userBean = LoginStatusUtil.getLoginDataByBean(mContext);
        if (userBean == null) {
            ToastUtils.showShort(mContext, "没有已登陆用户的信息");
            return;
        }
        //存在已登陆用户信息
        setInitUserInfo(userBean);
        mView.initInfos(userBean);
    }

    /**
     * 设置更改前用户信息
     *
     * @param userBean
     */
    private void setInitUserInfo(User userBean) {
        Log.d("初始化用户信息", userBean.toString());
        //显示头像
        mView.loadHeadImg(userBean.getHeadimg());
        //设置性别单选框
        mView.setSex(StringUtils.isEmpty(userBean.getSex()) ? "" : userBean.getSex());
        //设置birthday
        mView.setBirthday(StringUtils.isEmpty(userBean.getBirthday()) ? "" : userBean.getBirthday());
        //设置Nickname
        mView.setNickname(StringUtils.isEmpty(userBean.getNickName()) ? "" : userBean.getNickName());
        //location
        mView.setLocation(StringUtils.isEmpty(userBean.getUserArea()) ? "" : userBean.getUserArea());
    }

    /**
     * 当Fragment onDestroy()时调用
     */
    @Override
    public void onDestoryPresnter() {
        //取消提交更改
        if (mSup != null && !mSup.isUnsubscribed()) {
            mSup.unsubscribe();
            ToastUtils.showShort(App.getAppContext(), "取消更改");
//            Log.d(TAG, "onDestoryP..取消绑定(个人信息修改被取消)");
        }
        if (mSupUpdateImg != null && !mSupUpdateImg.isUnsubscribed()) {
            mSupUpdateImg.unsubscribe();
            ToastUtils.showShort(App.getAppContext(), "取消上传图片");
//            Log.d(TAG, "onDestoryP..取消绑定(个人信息修改被取消)");
        }
    }

    /**
     * onActivityResult调用
     *
     * @param requestCode
     * @param resultCode
     * @param data
     */
    @Override
    public void judgeActivityResult(int requestCode, int resultCode, Intent data) {
        //需要判断一下resultCode，即判断一下是运行时被取消了(back键 )还是运行正常 (Activity.RESULT_OK)
        if (resultCode == Activity.RESULT_OK) {
            switch (requestCode) {
                case CHOOSE_PICTURE_FROM_DISK:
                    startPhotoZoom(data.getData());
                    break;
                case TAKE_PICTURE:
                    //跳到图片裁切
                    startPhotoZoom(mTempUri);
                    break;
                case CROP_SMALL_PICTURE:
                    if (data != null) {
                        Bundle extras = data.getExtras();
                        if (extras != null) {
                            Bitmap photo = extras.getParcelable("data");
                            updateHeadImg(photo);
//                            String localPath = FileUtil.savePhoto(photo, DIR_NAME, SUB_DIR_NAME, HEAD_IMG_NAME);
                        }
                    }
                    break;
            }
        }
    }

    /*调用model 上传图片*/
    private void updateHeadImg(Bitmap bitmap) {
        //转换为二进制图片流
        byte[] bytes = BitmapUtil.getBitmapByte(bitmap);
        //Post请求
        Map<String, String> params = getUpdateImgParams(bytes);
        if (params == null) {
            return;
        }
        LogLongUtil.logD("上传头像参数", params.toString());
        //显示loading动画
        mView.showBaseLoading(true);

        mSupUpdateImg = new UpdateHeadImgModel().updateHeadImg(params)
                .subscribe(new Action1<UpdateImgResult>() {
                    @Override
                    public void call(UpdateImgResult updateImgResult) {
                        LogLongUtil.logI("上传成功的头像路径", updateImgResult.getData().getHeadimg());
                        judgeUpdateImgResult(updateImgResult);
                        mView.showBaseLoading(false);
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        throwable.printStackTrace();
                        ToastUtils.showLong(App.getAppContext(), "上传头像失败");
                        mView.showBaseLoading(false);
                    }
                });
    }

    /**
     * 上传头像成功后 判断 返回结果
     *
     * @param updateImgResult
     */
    private void judgeUpdateImgResult(UpdateImgResult updateImgResult) {
        if (updateImgResult == null)    return;
//        LogLongUtil.logD("成功上传头像", updateImgResult.toString());
        switch (updateImgResult.getCode()) {
            case 24001:
//                ToastUtils.showLong(mContext, "上传头像成功");
                if (updateImgResult.getData()==null)    {
                    saveHeadImgUrl2SharePrefence("");
                    mView.loadHeadImg("");
                    return;
                }
                //写入本地
                saveHeadImgUrl2SharePrefence(updateImgResult.getData().getHeadimg());
                //加载头像显示 出来
                mView.loadHeadImg(updateImgResult.getData().getHeadimg());
                break;
            default:
                ToastUtils.showLong(mContext, updateImgResult.getMessage()+"");
                break;
        }
    }

    /**
     * 保存头像url
     *
     * @param headImgUrl
     */
    private void saveHeadImgUrl2SharePrefence(String newHeadImgUrl) {
        Log.i("更新成功后返回的头像路径", newHeadImgUrl);
        User userBean = LoginStatusUtil.getLoginDataByBean(mContext);
        if (userBean == null) {
            return;
        }
        //更改用户头像
        userBean.setHeadimg(newHeadImgUrl);
        //重新写入登陆用户信息
        LoginStatusUtil.updateLoginedStatus(mContext, userBean);
    }

    /**
     * 上传 头像的 params
     *
     * @param bytes 图片的bytes (使用它转换成base64)
     * @return
     */
    private Map<String, String> getUpdateImgParams(byte[] image) {
        Map<String, String> params = new HashMap<>();
        //直接将图片指定为png
        String base64Img = BitmapUtil.byte2Base64(image);
        LogLongUtil.logD("UploadHeadPic的Base64图片", base64Img);

        User userBean = LoginStatusUtil.getLoginDataByBean(mContext);
        //事实上 不可能为空
        if (userBean == null) {
            ToastUtils.showShort(mContext.getApplicationContext(), "尚未保存登陆用户信息");
            return null;
        }
        params.put("userName", userBean.getUserName());
        params.put("headimg", base64Img);
        return params;
    }

    /*图片裁切*/
    private void startPhotoZoom(Uri uri) {
        if (uri == null) {
            ToastUtils.showShort(mContext.getApplicationContext(), "拍照失败。重试");
            return;
        }
        //传入 图片的uri
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uri, "image/*");
        //设置裁切
        intent.putExtra("crop", "true");
        //aspectX, aspectY 是宽高比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        //outputX outputY 是裁剪图片的宽度
        intent.putExtra("outputX", 150);
        intent.putExtra("outputY", 150);
        intent.putExtra("return-data", true);
        startActivityForResult(intent, CROP_SMALL_PICTURE);
    }


    /**
     * 确认修改
     * 当点击 确认按钮时 调用
     */
    @Override
    public void confirmModify(String nickname, String sex,  String location) {
        if (!isValidParams(nickname, sex, location)) return;
        Log.i(TAG, "要提交的参数.." + nickname + ".." + sex + ".." + location);
        //显示base的loading动画
        mView.showBaseLoading(true);
        final Map<String, String> params = getPostParams(nickname, sex, location);
        if (params == null)
            return;
        //post提交
        mSup = mModel.saveModifyUserInfo(params)
                .subscribe(new Action1<ModifyUserInfoResult>() {
                    @Override
                    public void call(ModifyUserInfoResult modifyUserInfoResult) {
                        //判断结果
                        judgeModifyUserInfoResult(modifyUserInfoResult, params);
                        mView.showBaseLoading(false);
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        ToastUtils.showShort(mContext.getApplicationContext(), "修改个人信息失败");
                        mView.showBaseLoading(false);
                        throwable.printStackTrace();
                    }
                });
    }

    /**
     * 正则匹配、输入的参数是否合法
     */
    private boolean isValidParams(String nickname, String sex, String location) {
        if (!RegexUtils.isValid(nickname, REG_NICKNAME)) {
            mView.showNicknameError("昵称不允许包含特殊字符");
            return false;
        }
        return true;
    }

    /**
     * 当提交个人信息后 返回的结果
     */
    private void judgeModifyUserInfoResult(ModifyUserInfoResult modifyUserInfoResult,
                                           Map<String, String> modifiedUserInfo) {
        switch (modifyUserInfoResult.getCode()) {
            case 24001 :
                //写入SharePreference
                updateUserInfo2SharePre(modifyUserInfoResult.getData(), modifiedUserInfo);
                //弹出提示
                ToastUtils.showLong(mContext, "修改个人信息成功！！！");
                //完成修改后 finish掉当前修改界面
                mView.finishCurrentModifyUserActivity();
                break;
            default:
                ToastUtils.showLong(mContext, modifyUserInfoResult.getMessage());
                break;
        }
        Log.d("修改个人信息", "msg:" + modifyUserInfoResult.getMessage()+".."+ modifyUserInfoResult.getCode());
    }

    /**
     * 更新个人资料 成功后
     * 更新SharePreference中保存的用户的个人的信息
     */
    private void updateUserInfo2SharePre(ModifyUseInfoBean bean,
                                         Map<String, String> modifiedUserInfo) {
        User user = LoginStatusUtil.getLoginDataByBean(mContext);
        if (user == null)
            return;
        if (bean == null)   return;

        user.setNickName(bean.getNickName());
        user.setSex(bean.getSex());
        user.setUserArea(bean.getUserArea());
        Log.d("更新后的User", user.toString());
        //保存回SharePreference
        LoginStatusUtil.updateLoginedStatus(mContext, user);
    }

    /**
     * 得到Post请求的参数  不为空 才加入
     *
     * @param nickname
     * @param sex
     * @param resume
     * @param birthday
     * @return
     */
    private Map<String, String> getPostParams(String nickName, String sex, String location) {
        Map<String, String> params = new HashMap<>();
        User userBean = LoginStatusUtil.getLoginDataByBean(mContext);
        //事实上 不可能为空
        if (userBean == null) {
            ToastUtils.showShort(mContext, "尚未保存登陆用户信息");
            return null;
        }
        params.put("userName", userBean.getUserName());
        //存入nickname
        params.put("nickName", nickName);
        //userArea
        params.put("userArea", location);
        //sex
        params.put("sex", sex);
        return params;
    }

    /**
     * 用户点击选择图片提示框
     */
    public void clickChoosePicDialog(int itemIndex) {
        //生成临时 图片 名
        TEMP_IMG_NAME = RandomUtils.getImgFilename(IMG_EXPAND_NAME);
        //生成上传头像参数 filename(就是临时图片名)
        mFilename = TEMP_IMG_NAME;
        Log.d("生成的图片名..", mFilename);

        switch (itemIndex) {
            case CHOOSE_PICTURE_FROM_DISK:
                clickChoosePictureFromDiskItem();
                break;
            case TAKE_PICTURE:
                clickTakePictureItem();
                break;
        }
    }


    /**
     * 从本地图库选择图片
     */
    public void clickChoosePictureFromDiskItem() {
        //选择本地图片
        Intent openAlbumIntent = new Intent(Intent.ACTION_GET_CONTENT);
        //选择文件类型 为图片
        openAlbumIntent.setType("image/*");
        //传入一个请求码
        startActivityForResult(openAlbumIntent, CHOOSE_PICTURE_FROM_DISK);
    }

    /**
     * 直接拍照选择图片
     */
    public void clickTakePictureItem() {
        //先请求摄像头访问权限
        requestCameraPermission();
        //打开照相机直接拍照
        Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        //指定临时照片的保存路径（SD卡），image.jpg为一个临时文件，每次拍照后这个图片都会被替换
        File imgFile = FileUtil.createFile(FileUtil.getSDFile(), TEMP_IMG_NAME);

        if (imgFile == null) {
            return;
        }
        //得到当前版本号
        if (SystemUtils.sCurrentSystemVersion < 24) {
            /*
             * Android 7.0以下版本 使用当前方式打开摄像头
             */
            mTempUri = Uri.fromFile(imgFile);
            openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mTempUri);
            try {
                startActivityForResult(openCameraIntent, TAKE_PICTURE);
            } catch (Exception e) {
                Log.e(TAG, "缺少摄像头访问权限 ");
                ToastUtils.showLong(mContext, "请打开摄像头访问权限");
                e.printStackTrace();
            }
        } else {
            /*
             * Android 7.0以上版本
             */
            ContentValues contentValues = new ContentValues(1);
            contentValues.put(MediaStore.Images.Media.DATA, imgFile.getAbsolutePath());
//            Uri uri = getContext().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues);
            mTempUri = mContext.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
            openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mTempUri);
            try {
                startActivityForResult(openCameraIntent, TAKE_PICTURE);
            } catch (Exception e) {
                Log.e(TAG, "缺少摄像头访问权限 ");
                ToastUtils.showLong(mContext, "请打开摄像头访问权限");
                e.printStackTrace();
            }
        }
    }

    /*请求摄像头访问权限*/
    private void requestCameraPermission() {
        /**查询是否存在权限要求SDK23*/
//        int hasCameraPermission = mContext.checkSelfPermission(android.Manifest.permission.CAMERA);
    }

    /**
     * 选择完图片后返回图片给当前Activity
     *
     * @param intent
     * @param requestCode
     */
    private void startActivityForResult(Intent intent, int requestCode) {
        ((Fragment) mView).startActivityForResult(intent, requestCode);
    }
}
